home *** CD-ROM | disk | FTP | other *** search
- /*
- * COLOR.C
- *
- * Code demonstrating the various uses of the ChooseColor common dialog.
- *
- * Copyright (c)1992 Microsoft Corporation, All Right Reserved
- *
- * Kraig Brockschmidt, Software Design Engineer
- * Microsoft Systems Developer Relations
- * One Microsoft Way
- * Redmond, WA 98052
- *
- * Internet : kraigb@microsoft.com
- * Compuserve: 70750,2344
- * Fax : (206)936-7329
- */
-
- #include <windows.h>
- #include <commdlg.h>
- #include <dlgs.h>
- #include <colordlg.h>
- #include <memory.h>
- #include "dialogs.h"
-
-
-
-
- //Array of the standard 16 colors.
- DWORD rgColors16[16]={RGB( 0, 0, 0), //Black
- RGB(128, 0, 0), //Dark red
- RGB( 0, 128, 0), //Dark green
- RGB(128, 128, 0), //Dark yellow
- RGB( 0, 0, 128), //Dark blue
- RGB(128, 0, 128), //Dark purple
- RGB( 0, 128, 128), //Dark aqua
- RGB(128, 128, 128), //Dark grey
- RGB(192, 192, 192), //Light grey
- RGB(255, 0, 0), //Light red
- RGB( 0, 255, 0), //Light green
- RGB(255, 255, 0), //Light yellow
- RGB( 0, 0, 255), //Light blue
- RGB(255, 0, 255), //Light purple
- RGB( 0, 255, 255), //Light aqua
- RGB(255, 255, 255), //White
- };
-
-
-
- /*
- * ColorDialogs
- *
- * Purpose:
- * Invokes variations on the ChooseColor common dialog depending
- * on the menu selection. Returns the chosen color to the caller.
- *
- * Parameters:
- * hWndOwner HWND to use as the owner of the dialog.
- * iDialog WORD indicating which dialog variation to invoke.
- *
- * Return Value:
- * COLORREF Chosen color. 0xFFFFFFFF on error (an invalid color)
- */
-
- COLORREF PASCAL ColorDialogs(HWND hWndOwner, WORD iDialog)
- {
- static BOOL fOpen=FALSE;
- COLORREF rgColors[16];
- BOOL fRet=FALSE;
- HRSRC hRes;
- CHOOSECOLOR cc;
- UINT i;
-
- /*
- * Prevent reentrancy in cases where cc.hwndOwner==NULL or in our
- * modeless case. Any other situation is modal so we cannot be
- * reentered anyway.
- */
- if (fOpen)
- {
- MessageBox(hWndOwner, "Color Dialog is already open", "ChooseColor", MB_OK);
- return (COLORREF)0xFFFFFFFF;
- }
-
-
- /*
- * The absolute minimum initialization before calling ChooseColor
- * is to zero out the CHOOSECOLOR structure, set the lStructSize
- * field, and set the lpCustColors field to point to an array of
- * 16 COLORREFs. lpCustColors cannot be NULL (ChooseColor will
- * fail) and cannot be non-NULL but invalid (ChooseColor will
- * repeatedly GP Fault). Note that initializing the array of
- * colors is not necessary.
- */
-
- memset(&cc, 0, sizeof(CHOOSECOLOR));
- cc.lStructSize=sizeof(CHOOSECOLOR);
- cc.lpCustColors=rgColors;
-
-
- /*
- * Initialize colors to shades of blue. This step is not absolutely
- * necessary, but given the user something more than random colors.
- */
- if (IDM_COLORABSOLUTEMINIMUM!=iDialog)
- {
- for (i=0; i<16; i++)
- rgColors[i]=RGB(0, 0, i*16);
- }
-
-
- switch (iDialog)
- {
- case IDM_COLORABSOLUTEMINIMUM:
- /*
- * When hWndOwner is not set, the dialog acts in a semi-modeless
- * fashion; you can switch back to the parent window but you
- * see little relationship between the dialog and the parent.
- * For example, the parent can overlap this dialog. Since it
- * acts modeless, we use the fOpen flag to prevent reentrancy.
- */
- fOpen=TRUE;
- fRet=ChooseColor(&cc);
- fOpen=FALSE;
- break;
-
-
- case IDM_COLORBASIC:
- /*
- * In basic operation we initialize the custom colors as desired,
- * give the dialog box an owner, and specify a default color in
- * rgbResult. In order to make that color in rgbResult show,
- * set the CC_RGBINIT flag.
- */
- cc.hwndOwner=hWndOwner;
- cc.rgbResult=RGB(0, 64, 0);
- cc.Flags=CC_RGBINIT;
- fRet=ChooseColor(&cc);
- break;
-
-
- case IDM_COLORFULLYOPEN:
- //Same as the basic scenario but with CC_FULLOPEN
- cc.hwndOwner=hWndOwner;
- cc.rgbResult=RGB(64, 0, 0);
- cc.Flags=CC_RGBINIT | CC_FULLOPEN;
- fRet=ChooseColor(&cc);
- break;
-
-
- case IDM_COLORPREVENTOPEN:
- //Same as the basic scenario but with CC_PREVENTFULLOPEN
- cc.hwndOwner=hWndOwner;
- cc.rgbResult=RGB(0, 0, 64);
- cc.Flags=CC_RGBINIT | CC_PREVENTFULLOPEN;
- fRet=ChooseColor(&cc);
- break;
-
-
- case IDM_COLORHOOKED:
- /*
- * Same as the basic scenario but with CC_SHOWHELP and
- * CC_ENABLEHOOK. We also have to initialize lpfnHook with a
- * procedure instance address from MakeProcInstance. Help
- * requests will send the registered HELPMSGSTRING to the parent
- * window procedure that can call WinHelp as necessary. We could
- * also process the WM_COMMAND message for the pshHelp control
- * to spawn WinHelp, avoiding the registered message.
- *
- * The hook is simple--it only changes the title bar of the
- * dialog--but for all common dialogs excep GetOpen/SavFileName
- * a hook is the only way to change the title.
- */
- cc.hwndOwner=hWndOwner;
- cc.rgbResult=RGB(0, 64, 0);
-
- //DLGHOOKPROC def'd in dialogs.h
- cc.lpfnHook=(DLGHOOKPROC)MakeProcInstance(ColorHook, hgInst);
-
- cc.Flags=CC_RGBINIT | CC_SHOWHELP | CC_ENABLEHOOK;
- fRet=ChooseColor(&cc);
-
- FreeProcInstance((FARPROC)cc.lpfnHook);
- break;
-
-
- case IDM_COLORCUSTOMIZEDTEMPLATE:
- /*
- * To customize the template we only have to provide an hInstance,
- * the name of the template in our resources, and the
- * CC_ENABLETEMPLATE flag. COMMDLG does the rest.
- */
- cc.hwndOwner=hWndOwner;
- cc.rgbResult=RGB(0, 64, 0);
- cc.hInstance=hgInst;
- cc.Flags =CC_ENABLETEMPLATE | CC_RGBINIT | CC_PREVENTFULLOPEN;
-
- //ChooseColor is the standard name of the dialog in COLOR.DLG
- (LPCSTR)cc.lpTemplateName="ChooseColor";
-
- fRet=ChooseColor(&cc);
- break;
-
-
- case IDM_COLORCUSTOMIZEDUSINGHANDLE:
- /*
- * To customize using a handle to a dialog resource, we first
- * find and load the resource, set it in hInstance, and set the
- * CC_ENABLETEMPLATEHANDLE flag. Using a handle is best when
- * you're building a dialog template dynamically or otherwise
- * do not have a named template that ChooseColor can just load
- * from your resources.
- *
- * In the modeless version of this dialog, we have to use
- * CC_FULLOPEN to allow the RGB edit controls to change with
- * our color selection. That way we can read the contents of
- * those controls to get the current color to apply.
- */
- cc.lpCustColors=rgColors16; //Standard 16 color array.
- cc.rgbResult=RGB(255, 255, 255);
- cc.Flags=CC_ENABLETEMPLATEHANDLE | CC_RGBINIT
- | CC_FULLOPEN | CC_ENABLEHOOK;
-
-
- /*
- * To create a modeless dialog, we do what er have before
- * for setting up a hook. However, we create an invisible
- * popup window to serve as the owner which allows us to
- * switch back to the main window. The dialog is only modal
- * for the popup window, and since that window is invisible,
- * we appear as modeless to the real parent. We still may need
- * the parent window, so we pass that ti the hook in lCustData.
- */
- cc.lCustData=hWndOwner;
- cc.hwndOwner=CreateWindow("ModelessPopup", "Parent"
- , WS_POPUP
- , 0, 0, 100, 100
- , hWndOwner, NULL, hgInst, NULL);
-
-
- cc.lpfnHook=(DLGHOOKPROC)MakeProcInstance(ColorModelessHook, hgInst);
-
- //Locate and get a handle to the dialog resource.
- hRes=FindResource(hgInst, "ChooseColor16", RT_DIALOG);
- cc.hInstance=(HANDLE)LoadResource(hgInst, hRes);
-
- fOpen=TRUE;
- fRet=ChooseColor(&cc);
- fOpen=FALSE;
-
- //Be sure to clean up the handle from LoadResource.
- FreeResource(cc.hInstance);
- FreeProcInstance((FARPROC)cc.lpfnHook);
- break;
-
-
-
- }
-
- if (!fRet)
- cc.rgbResult=(COLORREF)0xFFFFFFFF;
-
- return cc.rgbResult;
- }
-
-
-
-
-
-
- /*
- * ColorHook
- *
- * Purpose:
- * Dialog procedure hook that simply changes the caption bar of the
- * dialog in the WM_INITDIALOG message case. This is the only method
- * available to affect the caption bar in this and all other common
- * dialogs with the exception of GetOpen/SaveFileName.
- *
- * For all messages except WM_INITDIALOG, the hook is called before
- * any default processing takes place. For WM_INITDIALOG the hook
- * is called after the default procedure has done its thing.
- *
- * Parameters:
- * Standard parameter list for a dialog box procedure.
- *
- * Return Value:
- * UINT Non-Zero or Zero, indicating if the common dialog should
- * SKIP the message (non-zero) or not (zero). Don't confuse
- * with typical dialog box return values.
- */
-
- UINT FAR PASCAL ColorHook(HWND hDlg, UINT iMsg, UINT wParam, LONG lParam)
- {
- if (WM_INITDIALOG==iMsg)
- {
- SetWindowText(hDlg, "Select Window Background Color");
- return TRUE;
- }
-
- if (iMSGColorOK==iMsg)
- {
- /*
- * The COLOROKSTRING message is sent on pressing OK.
- * lParam points to the CHOOSECOLOR structure so you can
- * validate the contents of all 16 colors in lpCustColors.
- * If you accept them, return FALSE, otherwise return TRUE
- * and the dialog will not close.
- *
- * Here we just notify the user of the message and let them
- * choose to close or not.
- */
- wParam=MessageBox(hDlg
- , "COLOROKSTRING message received.\nClose Dialog?"
- , "ChooseColor", MB_YESNO);
-
- /*
- * If we aren't closing the dialog, send the SETRGBSTRING message
- * to select the default window background color, just for
- * demonstration.
- */
- if (IDNO==wParam)
- {
- SendMessage(hDlg, iMSGSetRGB, 0, (LONG)GetSysColor(COLOR_WINDOW));
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
-
-
-
- /*
- * ColorModelessHook
- *
- * Purpose:
- * ChooseColor hook procedure that overrides the OK button to mean
- * Apply, retriveing the current color selection from the RGB values
- * in the COLOR_RED, COLOR_GREEN, and COLOR_BLUE controls that are
- * in the dialog and updated, but hidden.
- *
- * Parameters:
- * Standard parameter list for a dialog box procedure.
- *
- * Return Value:
- * See ColorHook above.
- */
-
- UINT FAR PASCAL ColorModelessHook(HWND hDlg, UINT iMsg, UINT wParam, LONG lParam)
- {
- static HWND hWndParent;
- UINT r, g, b;
- BOOL fTemp;
- RECT rc;
- POINT pt;
-
- if (WM_INITDIALOG==iMsg)
- {
- //Button text already changed in the template. So just save the real parent.
- hWndParent=(HWND)((LPCHOOSECOLOR)lParam)->lCustData;
-
- //Reposition the window relative to the hWndParent
- pt.x=0;
- pt.y=0;
- ClientToScreen(hWndParent, &pt);
- GetWindowRect(hDlg, &rc);
-
- SetWindowPos(hDlg, NULL, pt.x+rc.left, pt.y+rc.top
- , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
- return TRUE;
- }
-
-
- if (WM_COMMAND==iMsg && IDOK==LOWORD(wParam))
- {
- //Get the current RGB values from the hidden, but active, edit controls.
- r=GetDlgItemInt(hDlg, COLOR_RED, &fTemp, FALSE);
- g=GetDlgItemInt(hDlg, COLOR_GREEN, &fTemp, FALSE);
- b=GetDlgItemInt(hDlg, COLOR_BLUE, &fTemp, FALSE);
-
- //Inform our main window that the color changed.
- SendMessage(hWndParent, USER_CHANGECOLOR, 0, RGB(r,g,b));
-
- //Tell the default procedure to skip this message.
- return TRUE;
- }
-
- return FALSE;
- }
-